﻿using System;
using System.Windows.Forms;
using System.ComponentModel.Design;
using System.ComponentModel;
using System.Runtime.InteropServices;

// win7-taskbar-progressbar v1.0, by BGSoft
// http://code.google.com/p/win7-taskbar-progressbar/

namespace BGSoft
{
    public partial class Win7TaskBarProgressBar : Component
    {
        private int Val = 0;
        private int Max = 100;
        private ProgressState style = ProgressState.NoProgress;
        private ContainerControl ownerForm;
        private bool Win7OrGreater = (Environment.OSVersion.Version.Major == 6 && Environment.OSVersion.Version.Minor >= 1) || (Environment.OSVersion.Version.Major > 6);
        
        public Win7TaskBarProgressBar() {}
        public Win7TaskBarProgressBar(ContainerControl parentControl)
        {
            ContainerControl = parentControl;
        }

        public ContainerControl ContainerControl
        {
            get { return ownerForm; }
            set
            {
                ownerForm = value;
                if(!ownerForm.Visible)
                  ((Form)ownerForm).Shown += Win7TaskBarProgressBar_Shown;
            }
        }

        public override ISite Site
        {
            set
            {
                base.Site = value;
                if (value == null) return;
                IDesignerHost service = value.GetService(typeof(IDesignerHost)) as IDesignerHost;
                if (service == null) return;
                IComponent rootComponent = service.RootComponent;

                ContainerControl = rootComponent as ContainerControl;
            }
        }
        

        void Win7TaskBarProgressBar_Shown(object sender, System.EventArgs e)
        {
            SendValue();
            SendStyle();
            ((Form)ownerForm).Shown -= Win7TaskBarProgressBar_Shown;
        }
        
        [DefaultValue(0)]
        public int Value
        {
            get { return Val; }
            set
            {
                Val = value;
                SendValue();
            }
        }
        [DefaultValue(100)]
        public int Maximum
        {
            get { return Max; }
            set
            {
                Max = value;
                SendValue();
            }
        }
        [DefaultValue(ProgressState.NoProgress)]
        public ProgressState Style
        {
            get { return style; }
            set
            {
                style = value;
                SendStyle();
            }
        }

        public enum ProgressState
        {
            NoProgress = 0,
            Indeterminate = 0x1,
            Normal = 0x2,
            Error = 0x4,
            Paused = 0x8
        }

        private void SendStyle()
        {
            if (Win7OrGreater)
                TaskbarList.SetProgressState(ownerForm.Handle, style);
        }

        private void SendValue()
        {
            if ((style != ProgressState.NoProgress) && (style != ProgressState.Indeterminate) && Win7OrGreater)
                TaskbarList.SetProgressValue(ownerForm.Handle, (ulong)Val, (ulong)Max);
        }

        [GuidAttribute("56FDF344-FD6D-11d0-958A-006097C9A090")]
        [ComImportAttribute()]
        internal class CTaskbarList { }
        private static ITaskbarList3 _taskbarList;
        internal static ITaskbarList3 TaskbarList
        {
            get
            {
                if (_taskbarList == null)
                {
                    lock (typeof(Win7TaskBarProgressBar))
                    {
                        if (_taskbarList == null)
                        {
                            _taskbarList = (ITaskbarList3)new CTaskbarList();
                            _taskbarList.HrInit();
                        }
                    }
                }
                return _taskbarList;
            }
        }

        [GuidAttribute("ea1afb91-9e28-4b86-90e9-9e9f8a5eefaf")]
        [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
        internal interface ITaskbarList3
        {
            void HrInit();
            void AddTab(IntPtr hwnd);
            void DeleteTab(IntPtr hwnd);
            void ActivateTab(IntPtr hwnd);
            void SetActiveAlt(IntPtr hwnd);
            void MarkFullscreenWindow(IntPtr hwnd, bool fFullscreen);
            void SetProgressValue(IntPtr hwnd, UInt64 ullCompleted, UInt64 ullTotal);
            void SetProgressState(IntPtr hwnd, ProgressState tbpFlags);
        }

    }
}
